package com.miniserver.tql.database;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;

import com.miniserver.tql.database.model.TNode;

/**
 * 数据访问更改执行接口
 * 
 * 可以通过execute执行非数据库操作，
 * 
 * 数据交换通过context进行，粘合其他非数据库操作
 * 
 * 如果执行出现错误，自动清理事务，返回错误提示
 * 
 */
public interface DatabaseEngine extends Cloneable {

	/**
	 * 处理访问请求，根据配置文件通过反射执行功能，输出返回结果
	 * 
	 * @param modelConfig
	 *            配置的方法
	 * @param context
	 *            参数和中间结果
	 * @return
	 * @throws Exception
	 */
	String handleRequest(ModelConfiguration modelConfig, Map<String, String> values) throws Exception;

	/**
	 * 开始事务处理
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void beginTrans(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 结束事务处理
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void endTrans(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 执行查询请求，输出查询结果或者中间结果
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void query(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 执行更新请求，也可以输出结果
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void update(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 执行一个非数据库操作,参数和结果通过context传递
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void execute(EngineContext context, TNode tNode) throws Exception;

	/**
	 * route 执行检查语句,与给定的变量比较,
	 * 
	 * <li>大于变量执行type=1的子节点;</li>
	 * 
	 * <li>相等执行type=0的子节点；</li>
	 * 
	 * <li>小于执行type=-1的子节点</li>
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void tif(EngineContext context, TNode tNode) throws Exception;

	void tthrow(EngineContext context, TNode tNode) throws Exception;

	/**
	 * map 获取传入的值,根据传入的值执行不同的操作
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void tswitch(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 保存一些中间结果到context中
	 * 
	 * @param context
	 * @param tNode
	 * @param query
	 * @throws Exception
	 */
	void set(EngineContext context, TNode tNode, Query query) throws Exception;

	/**
	 * 保存一些中间结果到context中
	 * 
	 * @param context
	 * @param tNode
	 */
	void clone(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 对query结果的每一行执行对应的操作，如子查询或更新
	 * 
	 * @param context
	 * @param tNode
	 * @param query
	 * @throws Exception
	 */
	void foreach(EngineContext context, TNode tNode, Query query) throws Exception;

	/**
	 * 获取ResultSet的TableName
	 * 
	 * @param rs
	 * @return
	 * @throws Exception
	 */
	String getTableName(EngineContext context, ResultSet rs) throws Exception;

	/**
	 * 
	 * @param stmt
	 * @param paramIdx
	 * @param value
	 * @throws Exception
	 */
	void bindParameter(PreparedStatement stmt, int paramIdx, String value) throws Exception;

	/**
	 * 指示其所有子节点都是针对物理数据库的
	 * 
	 * 同时该函数将关闭内存数据库, 如果事务没有提交将执行回滚操作
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void executeBackend(EngineContext context, TNode tNode) throws Exception;

	/**
	 * * 指示其所有子节点都是针对内存数据库的
	 * 
	 * 同时该函数将关闭物理数据库, 如果事务没有提交将执行回滚操作
	 * 
	 * @param context
	 * @param tNode
	 * @throws Exception
	 */
	void executeMemdb(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 执行tNode指定的代码
	 * 
	 * @param context
	 * @param tNode
	 */
	void invoke(EngineContext context, TNode tNode) throws Exception;

	/**
	 * 缓存数据 超时时间单位为秒 0为一个月
	 * 
	 * @param context
	 * @param tFuncNode
	 */
	void cache(EngineContext context, TNode tFuncNode);

	public Object clone() throws CloneNotSupportedException;
}
